home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Musik / Misc / Amster / Source / chat.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-01  |  9.1 KB  |  351 lines

  1. /*
  2. ** Chat Window
  3. */
  4.  
  5. #include "include/config.h"
  6.  
  7. #include <stdio.h>
  8. #include <stdarg.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. #include "include/mui.h"
  13. #include <MUI/NListview_mcc.h>
  14.  
  15. #include "include/gui.h"
  16. #include "include/msg.h"
  17. #include "include/channellist.h"
  18. #include "include/chat.h"
  19. #include "include/panel.h"
  20. #include "include/prefs.h"
  21. #include "include/napster.h"
  22. #include "include/protos.h"
  23. #include "amster_Cat.h"
  24.  
  25. channel chat_chans = NULL;
  26.  
  27. ULONG chat_new(struct IClass *cl, Object *obj, struct opSet *msg);
  28. MUIF chat_msgdisp(REG(a2) char **array, REG(a1) struct ChatMessage *m);
  29. void channel_part(struct chatdata *data);
  30. void chat_say(struct chatdata *data, char *user, char *msg);
  31. void chat_sayf(struct chatdata *data, char *user, char *msg, ...);
  32. void chat_saysys(struct chatdata *data, char *msg);
  33. void chat_command(struct chatdata *data);
  34.  
  35.  
  36. MUIF chat_dispatch(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  37. {
  38.     struct chatdata *data;
  39.  
  40.     switch(msg->MethodID) {
  41.         case OM_NEW:
  42.             return(chat_new(cl, obj, (APTR)msg));
  43.         case CHAT_COMMAND:
  44.             data = INST_DATA(cl, obj);
  45.             chat_command(data);
  46.             return(0);
  47.         case CHAT_JOINCHANNEL:
  48.             data = INST_DATA(cl, obj);
  49.             if (!gui_napon) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
  50.             else {
  51.                 data->chn.name = strdup((char *)(((muimsg)msg)->arg1));
  52.                 nap_sendbuf(NAPC_CHANNELJOIN, data->chn.name);
  53.                 data->chn.joinflag = 1;
  54.             }
  55.             return(0);
  56.         case CHAT_JOINACK:
  57.             data = INST_DATA(cl, obj);
  58.             data->chn.joinflag = 2;
  59.             set(data->chantxt, MUIA_Text_Contents, data->chn.name);
  60.             chat_sayf(data,"\33b-->", (char *)MSG_CHAT_JOINED_YOU, data->chn.name);
  61.             return(0);
  62.         case CHAT_PUBLICMSGRECV:
  63.             data = INST_DATA(cl, obj);
  64.             if (stricmp(prf->user, (char *)(((muimsg)msg)->arg1)) != 0)
  65.                 chat_say(data, (char *)(((muimsg)msg)->arg1), (char *)(((muimsg)msg)->arg2));
  66.                 /* Only show messages from others */
  67.             return(0);
  68.         case CHAT_JOINMSG:
  69.             data = INST_DATA(cl, obj);
  70.             chat_sayf(data, "\33b-->", (char *)MSG_CHAT_JOINED_THIS, (char *)(((muimsg)msg)->arg1), (int)(((muimsg)msg)->arg2), nap_linktype[(int)(((muimsg)msg)->arg3)]);
  71.         case CHAT_USERLIST:
  72.             data = INST_DATA(cl, obj);
  73.             /* TODO: Use the ChannelUserData struct and create a display book for the userlist */
  74.             DoMethod(data->userlist, MUIM_NList_InsertSingle, (char *)(((muimsg)msg)->arg1), MUIV_NList_Insert_Bottom);
  75.             return(0);
  76.         case CHAT_USERPART:
  77.             {
  78.             int i;
  79.             char *cuser;
  80.             data = INST_DATA(cl, obj);
  81.  
  82.             chat_sayf(data,"\33b<--", (char *)MSG_CHAT_PART_THIS, (char *)(((muimsg)msg)->arg1));
  83.  
  84.             for (i=0; ; i++) {
  85.                 DoMethod(data->userlist, MUIM_NList_GetEntry, i, &cuser);
  86.                 if (!cuser) break;
  87.                 if (strcmp((char *)(((muimsg)msg)->arg1), cuser) == 0) {
  88.                     DoMethod(data->userlist, MUIM_NList_Remove, i);
  89.                     break;
  90.                 }
  91.             }
  92.  
  93.             return(0);
  94.             }
  95.         case CHAT_CHANNELPART:
  96.             data = INST_DATA(cl, obj);
  97.             if (data->chn.name) nap_sendbuf(NAPC_CHANNELPART, data->chn.name);
  98.             DoMethod(gui->iconpanel, PANEL_DISPOSECHAT, obj);
  99.             return(0);
  100.         case CHAT_CHANNELTOPIC:
  101.             data = INST_DATA(cl, obj);
  102.             set(data->topicstr, MUIA_String_Contents, ((muimsg)msg)->arg1);
  103.             return(0);
  104.  
  105.     }
  106.     return(DoSuperMethodA(cl, obj, msg));
  107. }
  108.  
  109.  
  110. ULONG chat_new(struct IClass *cl, Object *obj, struct opSet *msg)
  111. {
  112.     static struct Hook msgdispHook = { {0,0}, &chat_msgdisp, NULL, NULL };
  113.     struct chatdata *data;
  114.     Object *rect, *chantxt, *topicstr, *msglist, *userlist, *msgstr;
  115.  
  116.     obj = (Object *)DoSuperNew(cl, obj,
  117.         MUIA_HelpNode, "chat",
  118.         MUIA_Window_Title, MSG_CHAT_TITLE,
  119.         MUIA_Window_ID, MAKE_ID('C','H','A','T'),
  120.         WindowContents, VGroup,
  121.             Child, rect = HGroup,
  122.                 Child, chantxt = TextObject,
  123.                     MUIA_HorizWeight, 0,
  124.                     MUIA_Text_Contents, MSG_CHAT_NONEJOINED,
  125.                 End,
  126.                 Child, topicstr = StringObject,
  127.                     StringFrame,
  128.                     MUIA_CycleChain, 1,
  129.                 End,
  130.             End,
  131.             Child, HGroup,
  132.                 Child, NListviewObject,
  133.                     MUIA_HorizWeight, 75,
  134.                     MUIA_NListview_NList, msglist = NListObject,
  135.                         ReadListFrame,
  136.                         MUIA_NList_Input, FALSE,
  137.                         MUIA_NList_Format, "BAR P=\33r,",
  138.                         MUIA_NList_DisplayHook, &msgdispHook,
  139.                         MUIA_NList_DefaultObjectOnClick, FALSE,
  140.                         MUIA_NList_AutoVisible, TRUE,
  141.                         MUIA_NList_AutoCopyToClip, TRUE,
  142.                         MUIA_NList_TypeSelect, MUIV_NList_TypeSelect_Char,
  143.                     End,
  144.                 End,
  145.                 Child, BalanceObject, End,
  146.                 Child, NListviewObject,
  147.                     MUIA_HorizWeight, 25,
  148.                     MUIA_NListview_NList, userlist = NListObject,
  149.                         InputListFrame,
  150.                         MUIA_NList_DefaultObjectOnClick, FALSE,
  151.                         MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String,
  152.                         MUIA_NList_DestructHook, MUIV_NList_DestructHook_String,
  153.                         MUIA_CycleChain, 1,
  154.                     End,
  155.                 End,
  156.             End,
  157.             Child, msgstr = StringObject,
  158.                 StringFrame,
  159.                 MUIA_CycleChain, 1,
  160.             End,
  161.         End,
  162.         TAG_MORE, msg->ops_AttrList);
  163.  
  164.     if (!obj) return(0);
  165.  
  166.     data = INST_DATA(cl,obj);
  167.     data->rect = rect;
  168.     data->chantxt = chantxt;
  169.     data->topicstr = topicstr;
  170.     data->msglist = msglist;
  171.     data->userlist = userlist;
  172.     data->msgstr = msgstr;
  173.  
  174.     data->chn.next = chat_chans;
  175.     chat_chans = &data->chn;
  176.     data->chn.joinflag = 0;
  177.     data->chn.name = NULL;
  178.     data->chn.win = obj;
  179.  
  180.     DoMethod(msgstr,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,obj,1,CHAT_COMMAND);
  181.     DoMethod(msgstr,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,obj,3,MUIM_Set,MUIA_Window_ActiveObject,msgstr);
  182.  
  183.     DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Application, 5, MUIM_Application_PushMethod, obj, 1, CHAT_CHANNELPART);
  184.  
  185.     return((ULONG)obj);
  186. }
  187.  
  188.  
  189. MUIF chat_msgdisp(REG(a2) char **array, REG(a1) struct ChatMessage *m)
  190. {
  191.     *array++ = m->Nick;
  192.     *array = m->Msg;
  193.  
  194.     return(0);
  195. }
  196.  
  197.  
  198. void chat_say(struct chatdata *data, char *user, char *msg)
  199. {
  200.     struct ChatMessage *m;
  201.  
  202.     m = malloc(sizeof(struct ChatMessage));
  203.     if (!m) return;
  204.  
  205.     m->Nick = strdup(user);
  206.     m->Msg = strdup(msg);
  207.  
  208.     DoMethod(data->msglist, MUIM_NList_InsertSingleWrap, m, MUIV_NList_Insert_Bottom, 2, NULL);
  209.     set(data->msglist, MUIA_NList_First, MUIV_NList_Active_Bottom);
  210. }
  211.  
  212.  
  213. void chat_sayf(struct chatdata *data, char *user, char *msg, ...)
  214. {
  215.     static char buf[1024];
  216.     va_list ap;
  217.  
  218.     va_start(ap, msg);
  219.     vsprintf(buf, msg, ap);
  220.     va_end(ap);
  221.     chat_say(data, user, buf);
  222. }
  223.  
  224.  
  225. void chat_saysys(struct chatdata *data, char *msg)
  226. {
  227.     chat_say(data,"\33b***",msg);
  228. }
  229.  
  230.  
  231. void chat_command(struct chatdata *data)
  232. {
  233.     u_long tmp;
  234.     char *com;
  235.  
  236.     GetAttr(MUIA_String_Acknowledge, data->msgstr, &tmp);
  237.     com = (char *)tmp;
  238.  
  239.     if (com[0] == '/') {
  240.         if (strnicmp("join", com+1, 4) == 0 && strlen(com)>6) {
  241.             if (!gui_napon) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
  242.             else {
  243.                 if (data->chn.name) channel_part(data);
  244.                 /* Leave channel in this window before joining a new one. */
  245.  
  246.                 data->chn.name = strdup(com+6);
  247.                 nap_sendbuf(NAPC_CHANNELJOIN, data->chn.name);
  248.                 data->chn.joinflag = 1;
  249.             }
  250.         }
  251.         else if (stricmp("leave", com+1) == 0) {
  252.             if (!gui_napon) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
  253.             else channel_part(data);
  254.         }
  255.         else if (stricmp("list", com+1) == 0) {
  256.             DoMethod(gui->WI_ChannelList, MUIM_Set, MUIA_Window_Open, TRUE);
  257.             if (gui_napon) DoMethod(gui->WI_ChannelList, CHANLIST_UPDATE);
  258.         }
  259.  
  260.     }
  261.     else {
  262.         if (!gui_napon) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
  263.         else {
  264.             if (data->chn.joinflag>1) {
  265.                 chat_say(data, prf->user, com);
  266.                 sprintf(nap_buf,"%s %s", data->chn.name, com);
  267.                 nap_send(NAPC_PUBLICMSGSEND);
  268.             }
  269.             else {
  270.                 chat_saysys(data, (char *)MSG_CHAT_NOTJOINED);
  271.             }
  272.         }
  273.     }
  274.  
  275.     set(data->msgstr, MUIA_String_Contents, NULL);
  276. }
  277.  
  278.  
  279. void channel_part(struct chatdata *data)
  280. {
  281.     u_long item;
  282.  
  283.     nap_sendbuf(NAPC_CHANNELPART, data->chn.name);
  284.     chat_sayf(data,"\33b<--", (char *)MSG_CHAT_PART_YOU, data->chn.name);
  285.  
  286.     set(data->userlist, MUIA_NList_Quiet, MUIV_NList_Quiet_Visual);
  287.     while (1) {
  288.         DoMethod(data->userlist, MUIM_NList_GetEntry, 0, &item);
  289.         if (!item) break;
  290.         DoMethod(data->userlist, MUIM_NList_Remove, MUIV_NList_Remove_First);
  291.     }
  292.     set(data->userlist, MUIA_NList_Quiet, MUIV_NList_Quiet_None);
  293.     /* Clear users from list */
  294.  
  295.     set(data->chantxt, MUIA_Text_Contents, MSG_CHAT_NONEJOINED);
  296.     /* Set channel name */
  297. }
  298.  
  299.  
  300. void chat_interpret(u_int com, char *data)
  301. {
  302.     channel c;
  303.  
  304.     switch (com) {
  305.         case NAPC_PUBLICMSGRECV:
  306.             c = chat_findchan(nap_token(&data));
  307.             if (!c) break;
  308.             DoMethod(c->win,CHAT_PUBLICMSGRECV,nap_token(&data),data);
  309.             break;
  310.         case NAPC_JOINACK:
  311.             c = chat_findchan(data);
  312.             if (!c) break;
  313.             DoMethod(c->win,CHAT_JOINACK);
  314.             break;
  315.         case NAPC_USERPART:
  316.             c = chat_findchan(nap_token(&data));
  317.             if (!c) break;
  318.             DoMethod(c->win,CHAT_USERPART,nap_token(&data));
  319.             break;
  320.         case NAPC_JOINMSG:
  321.             c = chat_findchan(nap_token(&data));
  322.             if (!c) break;
  323.             DoMethod(c->win, CHAT_JOINMSG, nap_token(&data), nap_itoken(&data), atoi(data));
  324.             break;
  325.         case NAPC_USERLIST:
  326.             c = chat_findchan(nap_token(&data));
  327.             if (!c) break;
  328.             DoMethod(c->win, CHAT_USERLIST, nap_token(&data), nap_itoken(&data), atoi(data));
  329.             break;
  330.         case NAPC_USERLISTEND:
  331.             break;
  332.         case NAPC_CHANNELTOPIC:
  333.             c = chat_findchan(nap_token(&data));
  334.             if (!c) break;
  335.             DoMethod(c->win, CHAT_CHANNELTOPIC, data);
  336.             break;
  337.     }
  338. }
  339.  
  340.  
  341. channel chat_findchan(char *name)
  342. {
  343.     channel c = chat_chans;
  344.  
  345.     while (c) {
  346.         if (stricmp(c->name, name) == 0) return(c);
  347.         c = c->next;
  348.     }
  349.     return(0);
  350. }
  351.